import { boot } from 'quasar/wrappers';

type EventCallback = (...args: any[]) => void;
type EventMap = Map<Events, EventCallback[]>;

const state = {
  events: new Map<Events, EventCallback[]>() as EventMap,
};

function $on(eventName: Events, fn: EventCallback): void {
  if (!state.events.has(eventName)) {
    state.events.set(eventName, []);
  }
  state.events.get(eventName)!.push(fn);
}

function $emit(eventName: Events, ...args: any[]): void {
  if (state.events.has(eventName)) {
    state.events.get(eventName)!.forEach((fn) => {
      fn(...args);
    });
  }
}

function $off(eventName: Events, fn: EventCallback): void {
  if (state.events.has(eventName)) {
    const eventList = state.events.get(eventName)!;
    const eventIndex = eventList.indexOf(fn);
    if (eventIndex > -1) {
      eventList.splice(eventIndex, 1);
    }
  }
}

function $destroy(): void {
  state.events.clear();
}
export enum Events {
  Create,
  Delete,
  Change,
  Ui,
}

export const EventBus = {
  $on,
  $emit,
  $off,
  $destroy,
};

export default boot(({ app }) => {
  app.config.globalProperties.$bus = EventBus;
});
